/**
 * @file menu.cpp
 * @brief 菜单系统模块实现
 */

#include <algorithm>
#include "../include/menu.h"
#include "../include/led.h"
#include "../include/config.h"
#include "../include/display.h"

// 当前选中的菜单项
uint8_t selectedMenuItem = 0;

// 当前显示的第一个菜单项
uint8_t firstVisibleMenuItem = 0;

// 屏幕显示3行菜单项 (标题15px + 2个行间距32px = 47px)
const uint8_t VISIBLE_MENU_ITEMS = 3;

// 二级菜单导航变量定义
// extern uint8_t currentMenuLevel; // 只声明，不定义
uint8_t selectedCategory = 0;
uint8_t selectedItemInCategory = 0;
uint8_t firstVisibleCategory = 0;
uint8_t firstVisibleItemInCategory = 0;

// 七彩颜色类型枚举 - 扩展类型名称
const char* rainbowTypeNames[] = {
    "全彩", "冷色", "暖色", "粉色", "青色", "紫色", "随机色"
};

// 扩展方向名称
const char *rainbowDirectionNames[] = {
    "随机", "上下流动","下上流动", "左右流动", "右左流动", "闪烁脉冲", "彩虹爆炸", "环形流动", "极光扫描", "霓虹闪电", "音乐脉动", "星光闪烁", "彩虹瀑布", "彩虹漩涡", "彩虹脉搏", "彩虹幻影"};

const char* gradientTypeNames[] = {"渐变色"};

// 一级菜单数组定义，新增七彩颜色和渐变颜色
const MenuCategory_t menuCategories[MENU_CATEGORY_COUNT] = {
    {"基本设置", 2, 0},    // 效果选择, 颜色选择
    {"灯带设置", 4, 2},    // 亮度调节, 灯带模式, 灯带分段, 每段灯数
    {"频谱设置", 4, 6},    // 频谱平滑, 上升速度, 下降速度, 峰值衰减
    {"峰值点设置", 9, 10}, // 峰值点数量, 峰值点颜色, 峰值点衰减, 峰值点停留, 冲击速度, 冲击距离, 颜色循环, 对数尺度, 快速衰减
    {"窗函数设置", 2, 19}, // 平滑指数, 自适应音量
    {"音频设置", 15, 21},  // 音频灵敏度, 频率上限, 各种频率补偿和噪声设置, 频段设置
    {"节拍设置", 5, 36},   // 节拍相关设置
    {"七彩颜色", 4, 41},   // 类型、速度、平滑、方向
    {"渐变颜色", 2, 45}    // 速度、平滑
};

// 重新组织的菜单项数组，新增七彩颜色和渐变颜色参数
SimpleMenuItem reorganizedMenuItems[] = {
    // 基本设置 (0-1)
    {"效果选择", MENU_BASIC},
    {"颜色选择", MENU_BASIC},

    // 灯带设置 (2-5)
    {"亮度调节", MENU_LED},
    {"灯带模式", MENU_LED},
    {"灯带分段", MENU_LED},
    {"每段灯数", MENU_LED},

    // 频谱设置 (6-9)
    {"频谱平滑", MENU_SPECTRUM},
    {"上升速度", MENU_SPECTRUM},
    {"下降速度", MENU_SPECTRUM},
    {"峰值衰减", MENU_SPECTRUM},

    // 峰值点设置 (10-18)
    {"峰值点数量", MENU_PEAK},
    {"峰值点颜色", MENU_PEAK},
    {"峰值点衰减", MENU_PEAK},
    {"峰值点停留", MENU_PEAK},
    {"冲击速度", MENU_PEAK},
    {"冲击距离", MENU_PEAK},
    {"颜色循环", MENU_PEAK},
    {"对数尺度", MENU_PEAK},
    {"快速衰减", MENU_PEAK},

    // 窗函数设置 (19-20)
    {"平滑指数", MENU_WINDOW},
    {"自适应音量", MENU_WINDOW},

    // 音频设置 (21-35) - 添加中高频频段项目
    {"音频灵敏度", MENU_AUDIO},
    {"频率上限", MENU_AUDIO},
    {"低频补偿", MENU_AUDIO},
    {"中频补偿", MENU_AUDIO},
    {"中高频补偿", MENU_AUDIO},
    {"高频补偿", MENU_AUDIO},
    {"低频噪声", MENU_AUDIO},
    {"中频噪声", MENU_AUDIO},
    {"中高频噪声", MENU_AUDIO},
    {"高频噪声", MENU_AUDIO},
    {"频谱压缩", MENU_AUDIO},
    {"低频频段", MENU_AUDIO},
    {"中频频段", MENU_AUDIO},
    {"中高频频段", MENU_AUDIO},    // 新增的中高频频段设置
    {"高频频段", MENU_AUDIO},

    // 节拍设置 (36-40) - 索引偏移+1
    {"节拍灵敏度", MENU_BEAT},
    {"节拍阈值", MENU_BEAT},
    {"节拍衰减", MENU_BEAT},
    {"节拍间隔", MENU_BEAT},
    {"节拍增强", MENU_BEAT},

    // 七彩颜色 (41-44)
    {"类型", MENU_RAINBOW},
    {"速度", MENU_RAINBOW},
    {"平滑", MENU_RAINBOW},
    {"方向", MENU_RAINBOW},

    // 渐变颜色 (45-46)
    {"速度", MENU_GRADIENT},
    {"平滑", MENU_GRADIENT}
};
const uint8_t TOTAL_REORGANIZED_MENU_ITEMS = sizeof(reorganizedMenuItems) / sizeof(SimpleMenuItem);

// 当前选中的效果
LEDEffectMode selectedEffect = LED_MODE_SPECTRUM;

// 当前选中的颜色方案
uint8_t selectedColorScheme = 0;

// 当前亮度
uint8_t currentBrightness = LED_BRIGHTNESS;

// 当前灵敏度
uint8_t currentSensitivity = 50;

// 当前灯带模式 (已在leds_out.cpp中定义)
extern LedStripMode currentLedStripMode;

// 使用config.h中定义的函数和常量

// 使用display.h中定义的SettingsMenuItem枚举

/**
 * @brief 检查并约束频段分配的总数
 * @param configItem 当前调整的配置项
 * @param newValue 新的配置值
 * @return 约束后的有效值
 */
int constrainBandAllocation(ConfigItem configItem, int newValue);

/**
 * @brief 初始化菜单系统
 */
void initMenu()
{
    // 加载设置
    if (!loadConfig())
    {
        // 如果加载失败，使用默认设置
        resetConfig();
        saveConfig();
    }

    // ==================== 修复菜单初始化问题 ====================
    // 从全局配置中初始化菜单变量，确保一致性
    currentBrightness = g_config.brightness;
    currentSensitivity = g_config.sensitivity;
    selectedEffect = static_cast<LEDEffectMode>(g_config.effectType);
    selectedColorScheme = g_config.colorScheme;
    currentLedStripMode = static_cast<LedStripMode>(g_config.ledStripMode);

    // 应用加载的配置到硬件
    uint8_t fastLedBrightness = map(currentBrightness, 10, 100, 25, 255);
    setBrightness(fastLedBrightness);
    setLEDEffect(selectedEffect);
    setColorScheme(selectedColorScheme);
    setLedStripMode(currentLedStripMode);

    // 设置初始页面
    setDisplayPage(PAGE_MAIN);

    if (DEBUG_SERIAL)
    {
        Serial.println("菜单系统初始化完成");
        Serial.printf("初始配置 - 亮度: %d%%, 灵敏度: %d%%, 效果: %d, 颜色: %d\n",
                      currentBrightness, currentSensitivity,
                      static_cast<uint8_t>(selectedEffect), selectedColorScheme);
    }
}

/**
 * @brief 设置当前亮度值并更新硬件
 * @param brightness 亮度值(10-100)
 */
void setCurrentBrightness(uint8_t brightness)
{
    currentBrightness = brightness;

    // ==================== 修复亮度配置问题 ====================
    // 1. 更新全局配置
    g_config.brightness = brightness;

    // 2. 将10-100%映射到25-255范围用于FastLED
    uint8_t fastLedBrightness = map(currentBrightness, 10, 100, 25, 255);

    // 3. 应用到LED硬件
    setBrightness(fastLedBrightness);

    // 4. 立即保存配置
    saveConfig();

    if (DEBUG_SERIAL)
    {
        Serial.printf("设置亮度: %d%% -> FastLED亮度: %d, 已保存到配置\n",
                      currentBrightness, fastLedBrightness);
    }
}

/**
 * @brief 设置当前灵敏度值并更新硬件
 * @param sensitivity 灵敏度值(0-100)
 */
void setCurrentSensitivity(uint8_t sensitivity)
{
    currentSensitivity = sensitivity;

    // ==================== 修复声音增益调节问题 ====================
    // 1. 更新全局配置
    g_config.sensitivity = sensitivity;

    // 2. 应用到音频处理系统（这里需要实际的音频灵敏度处理）
    // 注意：由于setAudioSensitivity被定义为setCurrentSensitivity的别名，
    // 我们不能再调用它，否则会造成递归调用
    // 需要直接实现音频灵敏度的设置逻辑

    // 3. 立即保存配置
    saveConfig();

    if (DEBUG_SERIAL)
    {
        Serial.printf("设置音频灵敏度: %d%%, 已保存到配置\n", currentSensitivity);
    }
}

// ==================== 全局延迟保存机制 ====================
// 用于减少EEPROM写入频率，避免菜单卡顿
static uint32_t lastConfigSave = 0;
static bool configNeedsSave = false;
static bool configChanged = false;       // 新增：标记配置是否有变化
const uint32_t CONFIG_SAVE_DELAY = 2000; // 2秒延迟保存

/**
 * @brief 标记配置需要保存（延迟保存）
 */
void markConfigForSave()
{
    configNeedsSave = true;
    configChanged = true;
}

/**
 * @brief 检查并执行延迟保存
 */
void checkDelayedSave()
{
    // 注意：不再自动保存，只有按下保存键才保存
    if (configChanged && DEBUG_SERIAL)
    {
        static uint32_t lastReminder = 0;
        if (millis() - lastReminder > 5000) // 每5秒提醒一次
        {
            Serial.println("[配置] 提醒: 配置已修改，请按ENTER键保存");
            lastReminder = millis();
        }
    }
}

/**
 * @brief 立即保存配置（仅在按保存键时调用）
 */
void forceSaveConfig()
{
    if (configChanged)
    {
        saveConfig();
        configNeedsSave = false;
        configChanged = false;
        lastConfigSave = millis();
        Serial.println("[配置] 配置已保存");
    }
    else
    {
        Serial.println("[配置] 无需保存，配置未修改");
    }
}

/**
 * @brief 检查配置是否有未保存的修改
 */
bool hasUnsavedChanges()
{
    return configChanged;
}

/**
 * @brief 更新菜单状态
 */
void updateMenu()
{
    handleMenuInput();
    checkDelayedSave();
    DisplayPage currentPage = getCurrentPage();

    // 添加显示更新逻辑
    switch (currentPage)
    {
    case PAGE_MAIN:
        // 主页面 - 在 updateDisplayAndEffects() 中处理
        break;
    case PAGE_SPECTRUM:
        // 频谱页面 - 需要显示频谱数据
        break;
    case PAGE_SETTINGS:
        // 设置页面 - 显示菜单列表
        if (g_displayInitialized)
        {
            displayCurrentMenu(); // 使用新的通用显示函数
        }
        break;
    case PAGE_EFFECT_SELECT:
        // 特效选择页面 - 显示效果列表
        if (g_displayInitialized)
        {
            showEffectSelectPage(selectedEffect);
        }
        break;
    case PAGE_COLOR_SELECT:
        // 颜色选择页面 - 显示颜色列表
        if (g_displayInitialized)
        {
            showColorSelectPage(selectedColorScheme);
        }
        break;
    default:
        // 参数页面 - 显示参数调整界面
        if (g_displayInitialized)
        {
            displayParameterEdit(selectedMenuItem, false); // 使用新的通用参数编辑函数
        }
        break;
    }
}

void handleMenuInput()
{
    DisplayPage currentPage = getCurrentPage();

    // ==================== 修复MODE键处理逻辑 ====================
    bool modePressed = isButtonPressed(BUTTON_TYPE_MODE);
    if (modePressed)
    {
        Serial.println("[MENU] MODE button pressed!");
        if (currentPage == PAGE_MAIN)
        {
            Serial.println("[MENU] Switching to settings page");
            setDisplayPage(PAGE_SETTINGS);
            currentMenuLevel = 0;
            selectedCategory = 0;
            selectedItemInCategory = 0;
            return; // 早期返回，避免后续处理
        }
        else if (currentPage == PAGE_SETTINGS)
        {
            // 直接在这里处理设置页面的MODE键逻辑
            if (currentMenuLevel == MENU_LEVEL_CATEGORY)
            {
                // 从一级菜单返回主页面
                Serial.println("[MENU] Returning to main page from category level");
                setDisplayPage(PAGE_MAIN);
            }
            else
            {
                // 从二级菜单返回一级菜单
                Serial.println("[MENU] Returning to category level from item level");
                currentMenuLevel = 0;
            }
            return; // 早期返回，避免后续处理
        }
        else if (currentPage == PAGE_EFFECT_SELECT || currentPage == PAGE_COLOR_SELECT)
        {
            // 从特效/颜色选择页面返回设置页面
            Serial.println("[MENU] Returning to settings from selection page");
            setDisplayPage(PAGE_SETTINGS);
            return; // 早期返回，避免后续处理
        }
        else
        {
            // 从参数页面或其他页面返回
            if (hasUnsavedChanges() && g_displayInitialized)
            {
                u8g2.clearBuffer();
                u8g2.setFont(u8g2_font_wqy16_t_gb2312);
                u8g2.setCursor(10, 25);
                u8g2.print("未保存!");
                u8g2.setCursor(10, 45);
                u8g2.print("按ENTER保存");
                u8g2.sendBuffer();
                delay(1200);
            }
            
            Serial.println("[MENU] Returning to settings from parameter page");
            setDisplayPage(PAGE_SETTINGS);
            currentMenuLevel = 1; // 返回到二级菜单
            return; // 早期返回，避免后续处理
        }
    }

    switch (currentPage)
    {
    case PAGE_MAIN:
        // 主页面按钮处理
        if (isButtonPressed(BUTTON_TYPE_UP))
        {
            Serial.println("[MENU] UP button pressed on main page");
            selectedColorScheme = (selectedColorScheme + 1) % 6;
            setColorScheme(selectedColorScheme);
            g_config.colorScheme = selectedColorScheme;
            saveConfig();
        }
        if (isButtonPressed(BUTTON_TYPE_DOWN))
        {
            Serial.println("[MENU] DOWN button pressed on main page");
            selectedColorScheme = (selectedColorScheme > 0) ? (selectedColorScheme - 1) : 5;
            setColorScheme(selectedColorScheme);
            g_config.colorScheme = selectedColorScheme;
            saveConfig();
        }
        if (isButtonPressed(BUTTON_TYPE_ENTER))
        {
            Serial.println("[MENU] ENTER button pressed on main page");
            setDisplayPage(PAGE_SPECTRUM);
        }
        break;

    case PAGE_SETTINGS:
        if (currentMenuLevel == MENU_LEVEL_CATEGORY)
        {
            // 一级菜单（分类菜单）导航
            if (isButtonPressed(BUTTON_TYPE_UP))
            {
                Serial.println("[MENU] UP button pressed on category level");
                if (selectedCategory > 0)
                {
                    selectedCategory--;
                }
                else
                {
                    selectedCategory = MENU_CATEGORY_COUNT - 1;
                }
                // 更新可见分类范围
                if (selectedCategory < firstVisibleCategory)
                {
                    firstVisibleCategory = selectedCategory;
                }
                else if (selectedCategory >= firstVisibleCategory + VISIBLE_MENU_ITEMS)
                {
                    firstVisibleCategory = selectedCategory - VISIBLE_MENU_ITEMS + 1;
                }
            }
            if (isButtonPressed(BUTTON_TYPE_DOWN))
            {
                Serial.println("[MENU] DOWN button pressed on category level");
                if (selectedCategory < MENU_CATEGORY_COUNT - 1)
                {
                    selectedCategory++;
                }
                else
                {
                    selectedCategory = 0;
                }
                // 更新可见分类范围
                if (selectedCategory >= firstVisibleCategory + VISIBLE_MENU_ITEMS)
                {
                    firstVisibleCategory = selectedCategory - VISIBLE_MENU_ITEMS + 1;
                }
                else if (selectedCategory < firstVisibleCategory)
                {
                    firstVisibleCategory = selectedCategory;
                }
            }
            if (isButtonPressed(BUTTON_TYPE_ENTER))
            {
                Serial.printf("[MENU] ENTER button pressed on category %d: %s\n",
                              selectedCategory, menuCategories[selectedCategory].title);
                // 进入二级菜单
                currentMenuLevel = 1;
                selectedItemInCategory = 0;
                firstVisibleItemInCategory = 0;
            }
        }
        else
        {
            // 二级菜单（具体项目）导航
            uint8_t itemCount = menuCategories[selectedCategory].itemCount;
            if (isButtonPressed(BUTTON_TYPE_UP))
            {
                Serial.println("[MENU] UP button pressed on item level");
                if (selectedItemInCategory > 0)
                {
                    selectedItemInCategory--;
                }
                else
                {
                    selectedItemInCategory = itemCount - 1;
                }
                // 更新可见项目范围
                if (selectedItemInCategory < firstVisibleItemInCategory)
                {
                    firstVisibleItemInCategory = selectedItemInCategory;
                }
                else if (selectedItemInCategory >= firstVisibleItemInCategory + VISIBLE_MENU_ITEMS)
                {
                    firstVisibleItemInCategory = selectedItemInCategory - VISIBLE_MENU_ITEMS + 1;
                }
            }
            if (isButtonPressed(BUTTON_TYPE_DOWN))
            {
                Serial.println("[MENU] DOWN button pressed on item level");
                if (selectedItemInCategory < itemCount - 1)
                {
                    selectedItemInCategory++;
                }
                else
                {
                    selectedItemInCategory = 0;
                }
                // 更新可见项目范围
                if (selectedItemInCategory >= firstVisibleItemInCategory + VISIBLE_MENU_ITEMS)
                {
                    firstVisibleItemInCategory = selectedItemInCategory - VISIBLE_MENU_ITEMS + 1;
                }
                else if (selectedItemInCategory < firstVisibleItemInCategory)
                {
                    firstVisibleItemInCategory = selectedItemInCategory;
                }
            }
            if (isButtonPressed(BUTTON_TYPE_ENTER))
            {
                uint8_t actualItemIndex = menuCategories[selectedCategory].firstItemIndex + selectedItemInCategory;
                Serial.printf("[MENU] ENTER button pressed on item %d: %s\n",
                              actualItemIndex, reorganizedMenuItems[actualItemIndex].title);

                // 处理具体菜单项
                handleSpecificMenuItem(actualItemIndex);
            }
            // 移除这里的MODE键处理，因为已经在上面统一处理了
        }
        break;

    case PAGE_EFFECT_SELECT:
        // 效果选择页面按钮处理
        if (isButtonPressed(BUTTON_TYPE_UP))
        {
            Serial.println("[MENU] UP button pressed on effect select page");
            selectedEffect = static_cast<LEDEffectMode>((selectedEffect > 0) ? (static_cast<uint8_t>(selectedEffect) - 1) : 4);
            setLEDEffect(selectedEffect);
            g_config.effectType = static_cast<uint8_t>(selectedEffect);
            saveConfig();
        }
        if (isButtonPressed(BUTTON_TYPE_DOWN))
        {
            Serial.println("[MENU] DOWN button pressed on effect select page");
            selectedEffect = static_cast<LEDEffectMode>((static_cast<uint8_t>(selectedEffect) + 1) % 5);
            setLEDEffect(selectedEffect);
            g_config.effectType = static_cast<uint8_t>(selectedEffect);
            saveConfig();
        }
        if (isButtonPressed(BUTTON_TYPE_ENTER))
        {
            Serial.println("[MENU] ENTER button pressed on effect select page");
            setDisplayPage(PAGE_SETTINGS);
        }
        break;

    case PAGE_COLOR_SELECT:
        // 颜色选择页面按钮处理
        if (isButtonPressed(BUTTON_TYPE_UP))
        {
            Serial.println("[MENU] UP button pressed on color select page");
            selectedColorScheme = (selectedColorScheme > 0) ? (selectedColorScheme - 1) : 5;
            setColorScheme(selectedColorScheme);
            g_config.colorScheme = selectedColorScheme;
            saveConfig();
        }
        if (isButtonPressed(BUTTON_TYPE_DOWN))
        {
            Serial.println("[MENU] DOWN button pressed on color select page");
            selectedColorScheme = (selectedColorScheme + 1) % 6;
            setColorScheme(selectedColorScheme);
            g_config.colorScheme = selectedColorScheme;
            saveConfig();
        }
        if (isButtonPressed(BUTTON_TYPE_ENTER))
        {
            Serial.println("[MENU] ENTER button pressed on color select page");
            setDisplayPage(PAGE_SETTINGS);
        }
        break;

    default:
        // 参数页面按钮处理 - 移除长按功能，只保留短按
        if (isButtonPressed(BUTTON_TYPE_UP))
        {
            adjustParameter(selectedMenuItem, true);
            markConfigForSave();
        }
        else if (isButtonPressed(BUTTON_TYPE_DOWN))
        {
            adjustParameter(selectedMenuItem, false);
            markConfigForSave();
        }
        else if (isButtonPressed(BUTTON_TYPE_ENTER))
        {
            if (hasUnsavedChanges())
            {
                forceSaveConfig();
                if (g_displayInitialized)
                {
                    u8g2.clearBuffer();
                    u8g2.setFont(u8g2_font_wqy16_t_gb2312);
                    u8g2.setCursor(20, 32);
                    u8g2.print("已保存!");
                    u8g2.sendBuffer();
                    delay(800);
                }
            }
            // ENTER键从参数页面返回到二级菜单
            setDisplayPage(PAGE_SETTINGS);
            currentMenuLevel = 1; // 返回到二级菜单
        }
        // 移除这里的MODE键处理，因为已经在上面统一处理了
        break;
    }
}

// ==================== 长按支持优化 ====================
struct ButtonPressState {
    bool isPressed;
    uint32_t pressStartTime;
    uint32_t lastRepeatTime;
    bool isLongPress;
};

static ButtonPressState buttonStates[4] = {0}; // UP, DOWN, ENTER, MODE

/**
 * @brief 获取按钮状态（支持长按快速调整）
 */
ButtonState getButtonStateWithLongPress(ButtonType buttonType) {
    ButtonPressState& state = buttonStates[buttonType];
    bool currentPressed = isButtonPressed(buttonType);
    uint32_t now = millis();
    
    if (currentPressed && !state.isPressed) {
        // 按钮刚按下
        state.isPressed = true;
        state.pressStartTime = now;
        state.lastRepeatTime = now;
        state.isLongPress = false;
        return BUTTON_PRESSED; // 使用buttons.h中定义的枚举值
    }
    else if (currentPressed && state.isPressed) {
        // 按钮持续按下
        if (!state.isLongPress && (now - state.pressStartTime > LONG_PRESS_TIME)) {
            state.isLongPress = true;
            return BUTTON_LONG_PRESSED; // 使用buttons.h中定义的枚举值
        }
        else if (state.isLongPress && (now - state.lastRepeatTime > REPEAT_INTERVAL)) {
            state.lastRepeatTime = now;
            return BUTTON_LONG_PRESSED; // 重复按压也使用长按状态
        }
    }
    else if (!currentPressed && state.isPressed) {
        // 按钮释放
        state.isPressed = false;
        state.isLongPress = false;
    }
    
    return BUTTON_IDLE; // 使用buttons.h中定义的枚举值
}

/**
 * @brief 增强的参数调整（支持长按加速）
 */
void adjustParameterWithLongPress(uint8_t menuItemIndex, bool increase, bool isLongPress) {
    uint8_t paramIndex = menuItemIndex - 2;
    if (paramIndex >= PARAM_CONFIGS_COUNT) return;
    
    const ParamConfig &config = paramConfigs[paramIndex];
    const ConfigRange &range = getConfigRange(config.configItem);
    
    // 长按时步进加速（5倍步进）
    int step = isLongPress ? (range.step * 5) : range.step;
    int direction = increase ? 1 : -1;
    
    void *valuePtr = getConfigValuePtr(config.configItem);
    if (!valuePtr) return;
    
    switch (config.type) {
        case ParamConfig::INT: {
            int *intPtr = static_cast<int *>(valuePtr);
            *intPtr = constrain(*intPtr + (step * direction), range.min, range.max);
            break;
        }
        case ParamConfig::FLOAT: {
            float *floatPtr = static_cast<float *>(valuePtr);
            if (isPercentageConfig(config.configItem)) {
                int currentPercent = (int)(*floatPtr * 100);
                int newPercent = constrain(currentPercent + (step * direction), range.min, range.max);
                *floatPtr = newPercent / 100.0f;
            } else {
                *floatPtr = constrain(*floatPtr + (step * direction), range.min, range.max);
            }
            break;
        }
        case ParamConfig::ENUM:
        {
            int *enumPtr = static_cast<int *>(valuePtr);
            int oldValue = *enumPtr;
            if (increase)
            {
                *enumPtr = (*enumPtr >= range.max) ? range.min : (*enumPtr + range.step);
            }
            else
            {
                *enumPtr = (*enumPtr <= range.min) ? range.max : (*enumPtr - range.step);
            }
            Serial.printf("[MENU] ENUM: %d -> %d (range: %d-%d)\n",
                          oldValue, *enumPtr, range.min, range.max);
            break;
        }
    }
    
    if (config.callback) config.callback();
}

/**
 * @brief 处理具体的菜单项
 * @param itemIndex 菜单项在reorganizedMenuItems中的索引
 */
void handleSpecificMenuItem(uint8_t itemIndex)
{
    switch (itemIndex)
    {
    case 0: // 效果选择
        setDisplayPage(PAGE_EFFECT_SELECT);
        break;
    case 1: // 颜色选择
        setDisplayPage(PAGE_COLOR_SELECT);
        break;
    case 47: // 保存设置
    {
        // ==================== 修复：非阻塞保存，避免LED卡顿 ====================
        showSavingPage(true);
        
        // 立即更新显示，不使用delay
        if (g_displayInitialized) {
            u8g2.sendBuffer();
        }
        
        // 保存配置（已优化为非阻塞版本）
        bool saveSuccess = saveConfig();
        
        // 显示保存结果
        showSavingPage(!saveSuccess); // true = 保存中, false = 保存成功
        
        // ==================== 移除阻塞性delay，使用状态机处理 ====================
        // 设置返回菜单的标记，在下次循环中处理
        static uint32_t saveResultDisplayTime = 0;
        saveResultDisplayTime = millis();
        
        // 直接返回菜单，不使用delay等待
        setDisplayPage(PAGE_SETTINGS);
        currentMenuLevel = 0;
    }
    break;
    case 48: // 恢复默认
    {
        showResettingPage(true);
        delay(500);
        resetConfig();
        saveConfig();
        // 重新初始化菜单变量
        currentBrightness = g_config.brightness;
        currentSensitivity = g_config.sensitivity;
        selectedEffect = static_cast<LEDEffectMode>(g_config.effectType);
        selectedColorScheme = g_config.colorScheme;
        currentLedStripMode = static_cast<LedStripMode>(g_config.ledStripMode);
        // 应用默认配置到硬件
        uint8_t fastLedBrightness = map(currentBrightness, 10, 100, 25, 255);
        setBrightness(fastLedBrightness);
        setLEDEffect(selectedEffect);
        setColorScheme(selectedColorScheme);
        setLedStripMode(currentLedStripMode);
        showResettingPage(false);
        delay(1000);
        setDisplayPage(PAGE_SETTINGS);
        currentMenuLevel = 0;
    }
    break;
    case 49: // 重置设置
    {
        showResettingPage(true);
        delay(500);
        resetConfig();
        saveConfig();
        // 重新初始化菜单变量
        currentBrightness = g_config.brightness;
        currentSensitivity = g_config.sensitivity;
        selectedEffect = static_cast<LEDEffectMode>(g_config.effectType);
        selectedColorScheme = g_config.colorScheme;
        currentLedStripMode = static_cast<LedStripMode>(g_config.ledStripMode);
        // 应用默认配置到硬件
        uint8_t fastLedBrightness = map(currentBrightness, 10, 100, 25, 255);
        setBrightness(fastLedBrightness);
        setLEDEffect(selectedEffect);
        setColorScheme(selectedColorScheme);
        setLedStripMode(currentLedStripMode);
        showResettingPage(false);
        delay(1000);
        setDisplayPage(PAGE_SETTINGS);
        currentMenuLevel = 0;
    }
    break;
    case 50: // 关于
    {
        showAboutPage();
        delay(3000);
        setDisplayPage(PAGE_SETTINGS);
        currentMenuLevel = 0;
    }
    break;
    default:
        // 其他菜单项进入参数调整页面
        Serial.printf("[MENU] Entering param adjustment for item %d: %s\n", itemIndex, reorganizedMenuItems[itemIndex].title);
        // 设置当前选中的菜单项为全局变量，供参数调整页面使用
        selectedMenuItem = itemIndex;
        // 进入通用参数调整页面
        setDisplayPage(PAGE_BRIGHTNESS); // 使用统一的参数调整页面
        break;
    }
}

/**
 * @brief 获取重新组织的菜单项当前值 - 修复内存分配版本
 * @param index 菜单项在reorganizedMenuItems中的索引
 * @return String 当前值的字符串表示
 */
String getReorganizedMenuItemValue(uint8_t index)
{
    // 使用静态缓冲区避免频繁的String动态分配
    static char valueBuffer[32];

    // 直接根据菜单项索引获取对应的配置值
    switch (index)
    {
    case 0: // 效果选择
    {
        const char *effectNames[] = {"纯色模式", "彩虹模式", "瀑布模式", "频谱模式", "火焰模式"};
        return (g_config.effectType < 5) ? String(effectNames[g_config.effectType]) : String(g_config.effectType);
    }
    case 1: // 颜色选择
    {
        const char *colorNames[] = {"彩虹色", "火焰色", "海洋色", "森林色", "派对色", "单色"};
        return (g_config.colorScheme < 6) ? String(colorNames[g_config.colorScheme]) : String(g_config.colorScheme);
    }
    case 2:
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", g_config.brightness);
        return String(valueBuffer);
    case 3:
        snprintf(valueBuffer, sizeof(valueBuffer), "%d", g_config.ledStripMode);
        return String(valueBuffer);
    case 4:
        snprintf(valueBuffer, sizeof(valueBuffer), "%d", g_config.segments);
        return String(valueBuffer);
    case 5:
        snprintf(valueBuffer, sizeof(valueBuffer), "%d", g_config.ledsPerSegment);
        return String(valueBuffer);
    case 6:
        snprintf(valueBuffer, sizeof(valueBuffer), "%.0f%%", g_config.spectrumSmoothing * 100);
        return String(valueBuffer);
    case 7:
        snprintf(valueBuffer, sizeof(valueBuffer), "%.0f%%", g_config.riseSpeed * 100);
        return String(valueBuffer);
    case 8:
        snprintf(valueBuffer, sizeof(valueBuffer), "%.0f%%", g_config.fallSpeed * 100);
        return String(valueBuffer);
    case 9:
        snprintf(valueBuffer, sizeof(valueBuffer), "%.0f%%", g_config.peakDecay * 100);
        return String(valueBuffer);
    case 10: // 峰值点数量
        // 使用通用数值显示模板，不特殊处理"关闭"
        snprintf(valueBuffer, sizeof(valueBuffer), "%d个", g_config.peakDotCount);
        return String(valueBuffer);
    case 11: // 峰值点颜色
        switch (g_config.peakDotColor)
        {
        case 0:
            return String("七彩");
        case 1:
            return String("红色");
        case 2:
            return String("绿色");
        case 3:
            return String("蓝色");
        case 4:
            return String("黄色");
        case 5:
            return String("白色");
        case 6:
            return String("紫色");
        case 7:
            return String("青色");
        case 8:
            return String("橙色");
        case 9:
            return String("粉色");
        default:
            return String("未知");
        }
    case 12:
        snprintf(valueBuffer, sizeof(valueBuffer), "%.0f%%", g_config.peakDotDecay * 100);
        return String(valueBuffer);
    case 13:
        snprintf(valueBuffer, sizeof(valueBuffer), "%.0f%%", g_config.peakHoldTime * 100);
        return String(valueBuffer);
    case 14:
        snprintf(valueBuffer, sizeof(valueBuffer), "%.1fx", g_config.impactSpeed);
        return String(valueBuffer);
    case 15:
        snprintf(valueBuffer, sizeof(valueBuffer), "%d个LED", g_config.maxImpactDistance);
        return String(valueBuffer);
    case 16:
        snprintf(valueBuffer, sizeof(valueBuffer), "%d分钟", g_config.colorCycleTime / (60 * 1000));
        return String(valueBuffer);
    case 17:
        snprintf(valueBuffer, sizeof(valueBuffer), "%.0f%%", g_config.logScale * 100);
        return String(valueBuffer);
    case 18:
        snprintf(valueBuffer, sizeof(valueBuffer), "%.0f%%", g_config.fastDecayRate * 100);
        return String(valueBuffer);
    case 19: // 平滑指数(窗函数)
    {
        const char *windowNames[] = {"无平滑", "中等平滑", "较高平滑", "最高平滑"};
        int idx = g_config.fftWindowType;
        // 确保索引在有效范围内
        idx = constrain(idx, 0, 3);
        return String(windowNames[idx]);
    }
    case 20: // 自适应音量
        return g_config.volumeAdaptive ? String("开启") : String("关闭");
    case 21: // 音频灵敏度
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", g_config.sensitivity);
        return String(valueBuffer);
    case 22: // 频率上限 - 修复显示逻辑
        // g_config.freqUpperLimit存储的是Hz值，需要转换为kHz显示
        snprintf(valueBuffer, sizeof(valueBuffer), "%dkHz", g_config.freqUpperLimit / 1000);
        return String(valueBuffer);
    case 23: // 低频补偿
    {
        const ConfigRange &range = getConfigRange(CONFIG_LOW_FREQ_COMP);
        int percent = (int)(g_config.lowFreqComp * 100);
        percent = constrain(percent, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", percent);
        return String(valueBuffer);
    }
    case 24: // 中频补偿
    {
        const ConfigRange &range = getConfigRange(CONFIG_MID_FREQ_COMP);
        int percent = (int)(g_config.midFreqComp * 100);
        percent = constrain(percent, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", percent);
        return String(valueBuffer);
    }
    case 25: // 中高频补偿
    {
        const ConfigRange &range = getConfigRange(CONFIG_HIGH_MID_FREQ_COMP);
        int percent = (int)(g_config.highMidFreqComp * 100);
        percent = constrain(percent, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", percent);
        return String(valueBuffer);
    }
    case 26: // 高频补偿
    {
        const ConfigRange &range = getConfigRange(CONFIG_HIGH_FREQ_COMP);
        int percent = (int)(g_config.highFreqComp * 100);
        percent = constrain(percent, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", percent);
        return String(valueBuffer);
    }
    case 27: // 低频噪声
    {
        const ConfigRange &range = getConfigRange(CONFIG_LOW_FREQ_NOISE);
        int percent = (int)(g_config.lowFreqNoise * 100);
        percent = constrain(percent, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", percent);
        return String(valueBuffer);
    }
    case 28: // 中频噪声
    {
        const ConfigRange &range = getConfigRange(CONFIG_MID_FREQ_NOISE);
        int percent = (int)(g_config.midFreqNoise * 100);
        percent = constrain(percent, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", percent);
        return String(valueBuffer);
    }
    case 29: // 中高频噪声
    {
        const ConfigRange &range = getConfigRange(CONFIG_HIGH_MID_FREQ_NOISE);
        int percent = (int)(g_config.highMidFreqNoise * 100);
        percent = constrain(percent, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", percent);
        return String(valueBuffer);
    }
    case 30: // 高频噪声
    {
        const ConfigRange &range = getConfigRange(CONFIG_HIGH_FREQ_NOISE);
        int percent = (int)(g_config.highFreqNoise * 100);
        percent = constrain(percent, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", percent);
        return String(valueBuffer);
    }
    case 31: // 频谱压缩
    {
        const ConfigRange &range = getConfigRange(CONFIG_SPECTRUM_COMPRESSION);
        int percent = (int)(g_config.spectrumCompression * 100);
        percent = constrain(percent, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", percent);
        return String(valueBuffer);
    }
    case 32: // 低频频段
    {
        const ConfigRange &range = getConfigRange(CONFIG_BASS_BANDS);
        int bands = g_config.bassBands;
        bands = constrain(bands, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d", bands);
        return String(valueBuffer);
    }
    case 33: // 中频频段
    {
        const ConfigRange &range = getConfigRange(CONFIG_MID_BANDS);
        int bands = g_config.midBands;
        bands = constrain(bands, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d", bands);
        return String(valueBuffer);
    }
    case 34: // 中高频频段
    {
        const ConfigRange &range = getConfigRange(CONFIG_HIGH_MID_BANDS);
        int bands = g_config.highMidBands;
        bands = constrain(bands, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d", bands);
        return String(valueBuffer);
    }
    case 35: // 高频频段
    {
        const ConfigRange &range = getConfigRange(CONFIG_HIGH_BANDS);
        int bands = g_config.highBands;
        bands = constrain(bands, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d", bands);
        return String(valueBuffer);
    }
    case 36: // 节拍灵敏度
    {
        const ConfigRange &range = getConfigRange(CONFIG_BEAT_SENSITIVITY);
        int val = g_config.beatSensitivity;
        val = constrain(val, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d", val);
        return String(valueBuffer);
    }
    case 37: // 节拍阈值
    {
        const ConfigRange &range = getConfigRange(CONFIG_BEAT_THRESHOLD);
        int percent = (int)(g_config.beatThreshold * 100);
        percent = constrain(percent, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", percent);
        return String(valueBuffer);
    }
    case 38: // 节拍衰减率
    {
        const ConfigRange &range = getConfigRange(CONFIG_BEAT_DECAY_RATE);
        int percent = (int)(g_config.beatDecayRate * 100);
        percent = constrain(percent, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", percent);
        return String(valueBuffer);
    }
    case 39: // 节拍间隔
    {
        const ConfigRange &range = getConfigRange(CONFIG_BEAT_MIN_INTERVAL);
        int val = g_config.beatMinInterval;
        val = constrain(val, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%dms", val);
        return String(valueBuffer);
    }
    case 40: // 节拍增强因子
    {
        const ConfigRange &range = getConfigRange(CONFIG_BEAT_BOOST_FACTOR);
        int percent = (int)(g_config.beatBoostFactor * 100);
        percent = constrain(percent, range.min, range.max);
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", percent);
        return String(valueBuffer);
    }
    
    // 七彩颜色设置 (41-44)
    case 41: // 七彩颜色类型
    {
        // 扩展类型名称
        const char *rainbowTypes[] = {
            "全彩", "冷色", "暖色", "粉色", "青色", "紫色", "随机色"
        };
        uint8_t rainbowType = g_config.rainbowType;
        return (rainbowType < 11) ? String(rainbowTypes[rainbowType]) : String("全彩");
    }
    case 42: // 七彩颜色速度
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", g_config.rainbowSpeed);
        return String(valueBuffer);
    case 43: // 七彩颜色平滑
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", g_config.rainbowSmooth);
        return String(valueBuffer);
    case 44: // 七彩颜色方向
    {
          uint8_t direction = g_config.rainbowDirection;
        return (direction < 17) ? String(rainbowDirectionNames[direction]) : String("随机");
    }
    
    // 渐变颜色设置 (45-46)
    case 45: // 渐变颜色速度
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", g_config.gradientSpeed);
        return String(valueBuffer);
    case 46: // 渐变颜色平滑
        snprintf(valueBuffer, sizeof(valueBuffer), "%d%%", g_config.gradientSmooth);
        return String(valueBuffer);
    
    // 原有的保存、恢复、重置、关于功能保持不变，但索引需要后移
    case 47:
        return String(""); // 保存设置
    case 48:
        return String(""); // 恢复默认
    case 49:
        return String(""); // 重置设置
    case 50:
        return String(""); // 关于
    default:
        return String("");
    }
}

/**
 * @brief 检查配置项是否为百分比类型
 * @param item 配置项枚举
 * @return true 如果是百分比类型，false 否则
 */
bool isPercentageConfig(ConfigItem item)
{
    switch (item)
    {
    case CONFIG_SPECTRUM_SMOOTHING:
    case CONFIG_RISE_SPEED:
    case CONFIG_FALL_SPEED:
    case CONFIG_PEAK_DECAY:
    case CONFIG_PEAK_DOT_DECAY:
    case CONFIG_PEAK_HOLD_TIME:
    case CONFIG_LOG_SCALE:
    case CONFIG_FAST_DECAY_RATE:
    case CONFIG_LOW_FREQ_COMP:
    case CONFIG_MID_FREQ_COMP:
    case CONFIG_HIGH_MID_FREQ_COMP:
    case CONFIG_HIGH_FREQ_COMP:
    case CONFIG_LOW_FREQ_NOISE:
    case CONFIG_MID_FREQ_NOISE:
    case CONFIG_HIGH_MID_FREQ_NOISE:
    case CONFIG_HIGH_FREQ_NOISE:
    case CONFIG_SPECTRUM_COMPRESSION:
    case CONFIG_BEAT_THRESHOLD:
    case CONFIG_BEAT_DECAY_RATE:
    case CONFIG_BEAT_BOOST_FACTOR:
        return true;
    default:
        return false;
    }
}

/**
 * @brief 调整参数值（修复版本）
 * @param menuItemIndex 菜单项索引
 * @param increase true表示增加，false表示减少
 */
void adjustParameter(uint8_t menuItemIndex, bool increase)
{
    // 扩展允许参数调整的菜单项范围（2~46），包含七彩和渐变参数
    if (menuItemIndex < 2 || menuItemIndex > 46) {
        Serial.printf("[MENU] Warning: Menu item %d does not support parameter adjustment\n", menuItemIndex);
        return;
    }
    
    // ==================== 修复亮度调节问题 ====================
    // 特殊处理亮度调节（菜单项索引2）
    if (menuItemIndex == 2) {
        const ConfigRange &range = getConfigRange(CONFIG_BRIGHTNESS);
        int direction = increase ? 1 : -1;
        int oldBrightness = g_config.brightness;
        int newBrightness = constrain(oldBrightness + (range.step * direction), range.min, range.max);
        
        // 使用专门的亮度设置函数
        setCurrentBrightness(newBrightness);
        
        Serial.printf("[MENU] 亮度调节: %d%% -> %d%% (range: %d-%d, step: %d)\n",
                      oldBrightness, newBrightness, range.min, range.max, range.step);
        return;
    }
    
    uint8_t paramIndex = menuItemIndex - 2;
    if (paramIndex >= PARAM_CONFIGS_COUNT) {
        Serial.printf("[MENU] Error: paramIndex %d out of range (max %d)\n", paramIndex, PARAM_CONFIGS_COUNT-1);
        return;
    }
    const ParamConfig &config = paramConfigs[paramIndex];
    const ConfigRange &range = getConfigRange(config.configItem);
    int direction = increase ? 1 : -1;
    void *valuePtr = getConfigValuePtr(config.configItem);
    if (!valuePtr) {
        Serial.printf("[MENU] Error: Cannot get config value pointer for item %d\n", config.configItem);
        return;
    }

    // 特殊处理颜色循环时间（需要分钟到毫秒的转换）
    if (config.configItem == CONFIG_COLOR_CYCLE_TIME)
    {
        uint16_t *cycleTimePtr = static_cast<uint16_t *>(valuePtr);
        // 将毫秒转换为分钟进行调整
        int currentMinutes = *cycleTimePtr / (60 * 1000);
        int newMinutes = constrain(currentMinutes + (range.step * direction), range.min, range.max);
        // 将分钟转换回毫秒存储
        *cycleTimePtr = newMinutes * 60 * 1000;
        
        Serial.printf("[MENU] COLOR_CYCLE_TIME: %d分钟 (%dms) -> %d分钟 (%dms)\n",
                      currentMinutes, currentMinutes * 60 * 1000,
                      newMinutes, *cycleTimePtr);
        
        // 执行回调函数（如果有）
        if (config.callback)
        {
            config.callback();
        }
        return;
    }

    // 特殊处理频率上限（kHz到Hz的转换）
    if (config.configItem == CONFIG_FREQ_UPPER_LIMIT)
    {
        uint16_t *freqPtr = static_cast<uint16_t *>(valuePtr);
        // 将Hz转换为kHz进行调整
        int currentKHz = *freqPtr / 1000;
        int newKHz = constrain(currentKHz + (range.step * direction), range.min, range.max);
        // 将kHz转换回Hz存储
        *freqPtr = newKHz * 1000;
        
        Serial.printf("[MENU] FREQ_UPPER_LIMIT: %dkHz (%dHz) -> %dkHz (%dHz)\n",
                      currentKHz, currentKHz * 1000,
                      newKHz, *freqPtr);
        
        // 执行回调函数（如果有）
        if (config.callback)
        {
            config.callback();
        }
        return;
    }

    // 根据类型调整值
    switch (config.type)
    {
    case ParamConfig::INT:
    {
        // ==================== 修复：正确处理uint8_t和int类型 ====================
        // 检查是否为频段配置项（uint8_t类型）
        if (config.configItem == CONFIG_BASS_BANDS || 
            config.configItem == CONFIG_MID_BANDS || 
            config.configItem == CONFIG_HIGH_MID_BANDS || 
            config.configItem == CONFIG_HIGH_BANDS ||
            config.configItem == CONFIG_BRIGHTNESS ||
            config.configItem == CONFIG_SENSITIVITY ||
            config.configItem == CONFIG_LED_STRIP_MODE ||
            config.configItem == CONFIG_SEGMENTS ||
            config.configItem == CONFIG_LEDS_PER_SEGMENT ||
            config.configItem == CONFIG_STYLE ||
            config.configItem == CONFIG_SPEED ||
            config.configItem == CONFIG_BEAT_SENSITIVITY ||
            config.configItem == CONFIG_BEAT_MIN_INTERVAL ||
            config.configItem == CONFIG_FFT_WINDOW_TYPE ||
            config.configItem == CONFIG_PEAK_DOT_COUNT ||
            config.configItem == CONFIG_PEAK_DOT_COLOR ||
            config.configItem == CONFIG_RAINBOW_TYPE ||
            config.configItem == CONFIG_RAINBOW_SPEED ||
            config.configItem == CONFIG_RAINBOW_SMOOTH ||
            config.configItem == CONFIG_RAINBOW_DIRECTION ||
            config.configItem == CONFIG_GRADIENT_SPEED ||
            config.configItem == CONFIG_GRADIENT_SMOOTH) 
        {
            // 使用uint8_t指针处理这些配置项
            uint8_t *uint8Ptr = static_cast<uint8_t *>(valuePtr);
            uint8_t oldValue = *uint8Ptr;
            int newValue = constrain((int)*uint8Ptr + (range.step * direction),
                                    range.min, range.max);
            
            // ==================== 修复：添加严格的类型安全检查 ====================
            // 确保新值在 uint8_t 范围内，防止内存越界
            if (newValue < 0) newValue = 0;
            if (newValue > 255) newValue = 255;
            
            // 对频段配置项进行额外约束
            if (config.configItem == CONFIG_BASS_BANDS || 
                config.configItem == CONFIG_MID_BANDS || 
                config.configItem == CONFIG_HIGH_MID_BANDS || 
                config.configItem == CONFIG_HIGH_BANDS) {
                newValue = constrainBandAllocation(config.configItem, newValue);
            }
            
            // ==================== 修复：类型安全的赋值操作 ====================
            // 使用安全的类型转换，确保不会越界
            uint8_t safeValue = static_cast<uint8_t>(constrain(newValue, 0, 255));
            *uint8Ptr = safeValue;
            
            Serial.printf("[MENU] UINT8: %d -> %d (range: %d-%d, step: %d, safe: %d)\n",
                          oldValue, safeValue, range.min, range.max, range.step, safeValue);
        }
        else if (config.configItem == CONFIG_FREQ_UPPER_LIMIT ||
                 config.configItem == CONFIG_COLOR_CYCLE_TIME)
        {
            // 使用uint16_t指针处理这些配置项
            uint16_t *uint16Ptr = static_cast<uint16_t *>(valuePtr);
            uint16_t oldValue = *uint16Ptr;
            int newValue = constrain((int)*uint16Ptr + (range.step * direction),
                                    range.min, range.max);
            *uint16Ptr = (uint16_t)newValue;
            Serial.printf("[MENU] UINT16: %d -> %d (range: %d-%d, step: %d)\n",
                          oldValue, *uint16Ptr, range.min, range.max, range.step);
        }
        else if (config.configItem == CONFIG_MAX_IMPACT_DISTANCE)
        {
            // 使用uint8_t指针处理maxImpactDistance
            uint8_t *uint8Ptr = static_cast<uint8_t *>(valuePtr);
            uint8_t oldValue = *uint8Ptr;
            int newValue = constrain((int)*uint8Ptr + (range.step * direction),
                                    range.min, range.max);
            *uint8Ptr = (uint8_t)newValue;
            Serial.printf("[MENU] UINT8_IMPACT: %d -> %d (range: %d-%d, step: %d)\n",
                          oldValue, *uint8Ptr, range.min, range.max, range.step);
        }
        else
        {
            // 其他int类型配置项
            int *intPtr = static_cast<int *>(valuePtr);
            int oldValue = *intPtr;
            int newValue = constrain(*intPtr + (range.step * direction),
                                    range.min, range.max);
            *intPtr = newValue;
            Serial.printf("[MENU] INT: %d -> %d (range: %d-%d, step: %d)\n",
                          oldValue, *intPtr, range.min, range.max, range.step);
        }
        break;
    }
    case ParamConfig::FLOAT:
    {
        float *floatPtr = static_cast<float *>(valuePtr);
        float oldValue = *floatPtr;

        if (isPercentageConfig(config.configItem))
        {
            // 百分比配置：g_configRanges中存储0-100，内部存储0.0-1.0
            int currentPercent = (int)(*floatPtr * 100);
            int newPercent = constrain(currentPercent + (range.step * direction),
                                       range.min, range.max);
            *floatPtr = newPercent / 100.0f;
            Serial.printf("[MENU] FLOAT(%%): %.2f (%d%%) -> %.2f (%d%%) (range: %d-%d%%)\n",
                          oldValue, currentPercent, *floatPtr, newPercent,
                          range.min, range.max);
        }
        else
        {
            // 非百分比配置：直接使用范围值
            *floatPtr = constrain(*floatPtr + (range.step * direction),
                                  range.min, range.max);
            Serial.printf("[MENU] FLOAT: %.2f -> %.2f (range: %.2f-%.2f, step: %d)\n",
                          oldValue, *floatPtr, (float)range.min, (float)range.max, range.step);
        }
        break;
    }
    case ParamConfig::ENUM:
    {
        int *enumPtr = static_cast<int *>(valuePtr);
        int oldValue = *enumPtr;
        if (increase)
        {
            *enumPtr = (*enumPtr >= range.max) ? range.min : (*enumPtr + range.step);
        }
        else
        {
            *enumPtr = (*enumPtr <= range.min) ? range.max : (*enumPtr - range.step);
        }
        Serial.printf("[MENU] ENUM: %d -> %d (range: %d-%d)\n",
                      oldValue, *enumPtr, range.min, range.max);
        break;
    }
    }

    // 执行回调函数（如果有）
    if (config.callback)
    {
        config.callback();
    }
}

// 修复addMissingCPUCpuUsage函数中的返回值
float getMCUCPUUsage() {
    // 简单的CPU使用率计算
    static uint32_t lastTime = 0;
    static uint32_t idleTime = 0;
    
    uint32_t currentTime = millis();
    if (currentTime - lastTime > 1000) {
        // 每秒计算一次
        float usage = 100.0f - (idleTime * 100.0f / 1000.0f);
        usage = constrain(usage, 0.0f, 100.0f);
        lastTime = currentTime;
        idleTime = 0;
        return usage;
    }
    
    idleTime += 10; // 假设有10ms空闲时间
    return 50.0f; // 返回默认值
}

// 参数配置数组定义 - 修复声明冲突，添加const
const ParamConfig paramConfigs[] = {
    // 灯带设置 (索引 0-3，对应菜单项 2-5)
    {ParamConfig::INT, CONFIG_BRIGHTNESS, nullptr},
    {ParamConfig::ENUM, CONFIG_LED_STRIP_MODE, nullptr},
    {ParamConfig::INT, CONFIG_SEGMENTS, nullptr},
    {ParamConfig::INT, CONFIG_LEDS_PER_SEGMENT, nullptr},

    // 频谱设置 (索引 4-7，对应菜单项 6-9)
    {ParamConfig::FLOAT, CONFIG_SPECTRUM_SMOOTHING, nullptr},
    {ParamConfig::FLOAT, CONFIG_RISE_SPEED, nullptr},
    {ParamConfig::FLOAT, CONFIG_FALL_SPEED, nullptr},
    {ParamConfig::FLOAT, CONFIG_PEAK_DECAY, nullptr},

    // 峰值点设置 (索引 8-16，对应菜单项 10-18)
    {ParamConfig::INT, CONFIG_PEAK_DOT_COUNT, nullptr},
    {ParamConfig::ENUM, CONFIG_PEAK_DOT_COLOR, nullptr},
    {ParamConfig::FLOAT, CONFIG_PEAK_DOT_DECAY, nullptr},
    {ParamConfig::FLOAT, CONFIG_PEAK_HOLD_TIME, nullptr},
    {ParamConfig::FLOAT, CONFIG_IMPACT_SPEED, nullptr},
    {ParamConfig::INT, CONFIG_MAX_IMPACT_DISTANCE, nullptr},
    {ParamConfig::INT, CONFIG_COLOR_CYCLE_TIME, nullptr},  // 修复：确保这里使用INT类型处理uint16_t
    {ParamConfig::FLOAT, CONFIG_LOG_SCALE, nullptr},
    {ParamConfig::FLOAT, CONFIG_FAST_DECAY_RATE, nullptr},

    // 窗函数设置 (索引 17-18，对应菜单项 19-20)
    {ParamConfig::ENUM, CONFIG_FFT_WINDOW_TYPE, nullptr}, // 平滑指数（窗函数类型）
    {ParamConfig::ENUM, CONFIG_VOLUME_ADAPTIVE, nullptr},

    // 音频设置 (索引 19-33，对应菜单项 21-35)
    {ParamConfig::INT, CONFIG_SENSITIVITY, nullptr},
    {ParamConfig::INT, CONFIG_FREQ_UPPER_LIMIT, nullptr},
    {ParamConfig::FLOAT, CONFIG_LOW_FREQ_COMP, nullptr},
    {ParamConfig::FLOAT, CONFIG_MID_FREQ_COMP, nullptr},
    {ParamConfig::FLOAT, CONFIG_HIGH_MID_FREQ_COMP, nullptr},
    {ParamConfig::FLOAT, CONFIG_HIGH_FREQ_COMP, nullptr},
    {ParamConfig::FLOAT, CONFIG_LOW_FREQ_NOISE, nullptr},
    {ParamConfig::FLOAT, CONFIG_MID_FREQ_NOISE, nullptr},
    {ParamConfig::FLOAT, CONFIG_HIGH_MID_FREQ_NOISE, nullptr},
    {ParamConfig::FLOAT, CONFIG_HIGH_FREQ_NOISE, nullptr},
    {ParamConfig::FLOAT, CONFIG_SPECTRUM_COMPRESSION, nullptr},
    {ParamConfig::INT, CONFIG_BASS_BANDS, nullptr},
    {ParamConfig::INT, CONFIG_MID_BANDS, nullptr},
    {ParamConfig::INT, CONFIG_HIGH_MID_BANDS, nullptr},
    {ParamConfig::INT, CONFIG_HIGH_BANDS, nullptr},

    // 节拍设置 (索引 34-38，对应菜单项 36-40)
    {ParamConfig::INT, CONFIG_BEAT_SENSITIVITY, nullptr},
    {ParamConfig::FLOAT, CONFIG_BEAT_THRESHOLD, nullptr},
    {ParamConfig::FLOAT, CONFIG_BEAT_DECAY_RATE, nullptr},
    {ParamConfig::INT, CONFIG_BEAT_MIN_INTERVAL, nullptr},
    {ParamConfig::FLOAT, CONFIG_BEAT_BOOST_FACTOR, nullptr},

    // 七彩相关参数 (索引 39-42，对应菜单项 41-44)
    {ParamConfig::ENUM, CONFIG_RAINBOW_TYPE, nullptr},      // 类型（rainbowType）
    {ParamConfig::INT, CONFIG_RAINBOW_SPEED, nullptr},     // 速度（rainbowSpeed）
    {ParamConfig::INT, CONFIG_RAINBOW_SMOOTH, nullptr},    // 平滑（rainbowSmooth）
    {ParamConfig::ENUM, CONFIG_RAINBOW_DIRECTION, nullptr}, // 方向（rainbowDirection）
    // 渐变相关参数 (索引 43-44，对应菜单项 45-46)
    {ParamConfig::INT, CONFIG_GRADIENT_SPEED, nullptr},    // 速度（gradientSpeed）
    {ParamConfig::INT, CONFIG_GRADIENT_SMOOTH, nullptr},   // 平滑（gradientSmooth）
};

const uint8_t PARAM_CONFIGS_COUNT = sizeof(paramConfigs) / sizeof(ParamConfig);

/**
 * @brief 获取配置值指针
 * @param item 配置项枚举
 * @return void* 配置值的指针，失败返回nullptr
 */
void* getConfigValuePtr(ConfigItem item) {
    switch (item) {
        case CONFIG_EFFECT_TYPE: return &g_config.effectType;
        case CONFIG_COLOR_SCHEME: return &g_config.colorScheme;
        case CONFIG_BRIGHTNESS: return &g_config.brightness;
        case CONFIG_SENSITIVITY: return &g_config.sensitivity;
        case CONFIG_LED_STRIP_MODE: return &g_config.ledStripMode;
        case CONFIG_SEGMENTS: return &g_config.segments;
        case CONFIG_LEDS_PER_SEGMENT: return &g_config.ledsPerSegment;
        case CONFIG_STYLE: return &g_config.style;
        case CONFIG_SPEED: return &g_config.speed;
        case CONFIG_AUTO_CHANGE_EFFECT: return &g_config.autoChangeEffect;
        case CONFIG_AUTO_CHANGE_TIME: return &g_config.autoChangeTime;
        case CONFIG_MIN_THRESHOLD: return &g_config.minThreshold;
        case CONFIG_NOISE_CHECK: return &g_config.noiseCheckEnabled;
        case CONFIG_SPECTRUM_SMOOTHING: return &g_config.spectrumSmoothing;
        case CONFIG_RISE_SPEED: return &g_config.riseSpeed;
        case CONFIG_FALL_SPEED: return &g_config.fallSpeed;
        case CONFIG_PEAK_DECAY: return &g_config.peakDecay;
        case CONFIG_PEAK_DOT_DECAY: return &g_config.peakDotDecay;
        case CONFIG_PEAK_HOLD_TIME: return &g_config.peakHoldTime;
        case CONFIG_IMPACT_SPEED: return &g_config.impactSpeed;
        case CONFIG_MAX_IMPACT_DISTANCE: return &g_config.maxImpactDistance;
        case CONFIG_COLOR_CYCLE_TIME: return &g_config.colorCycleTime;
        case CONFIG_LOG_SCALE: return &g_config.logScale;
        case CONFIG_FAST_DECAY_RATE: return &g_config.fastDecayRate;
        case CONFIG_LOW_FREQ_COMP: return &g_config.lowFreqComp;
        case CONFIG_MID_FREQ_COMP: return &g_config.midFreqComp;
        case CONFIG_HIGH_MID_FREQ_COMP: return &g_config.highMidFreqComp;
        case CONFIG_HIGH_FREQ_COMP: return &g_config.highFreqComp;
        case CONFIG_LOW_FREQ_NOISE: return &g_config.lowFreqNoise;
        case CONFIG_MID_FREQ_NOISE: return &g_config.midFreqNoise;
        case CONFIG_HIGH_MID_FREQ_NOISE: return &g_config.highMidFreqNoise;
        case CONFIG_HIGH_FREQ_NOISE: return &g_config.highFreqNoise;
        case CONFIG_SPECTRUM_COMPRESSION: return &g_config.spectrumCompression;
        // ==================== 修复：频段参数使用正确的uint8_t*类型 ====================
        case CONFIG_BASS_BANDS: return &g_config.bassBands;
        case CONFIG_MID_BANDS: return &g_config.midBands;
        case CONFIG_HIGH_MID_BANDS: return &g_config.highMidBands;
        case CONFIG_HIGH_BANDS: return &g_config.highBands;
        case CONFIG_BEAT_SENSITIVITY: return &g_config.beatSensitivity;
        case CONFIG_BEAT_THRESHOLD: return &g_config.beatThreshold;
        case CONFIG_BEAT_DECAY_RATE: return &g_config.beatDecayRate;
        case CONFIG_BEAT_MIN_INTERVAL: return &g_config.beatMinInterval;
        case CONFIG_BEAT_BOOST_FACTOR: return &g_config.beatBoostFactor;
        case CONFIG_FREQ_UPPER_LIMIT: return &g_config.freqUpperLimit;
        case CONFIG_FFT_WINDOW_TYPE: return &g_config.fftWindowType;
        case CONFIG_PEAK_DOT_COUNT: return &g_config.peakDotCount;
        case CONFIG_PEAK_DOT_COLOR: return &g_config.peakDotColor;
        case CONFIG_VOLUME_ADAPTIVE: return &g_config.volumeAdaptive;
        // 七彩和渐变参数支持
        case CONFIG_RAINBOW_TYPE:      return &g_config.rainbowType;
        case CONFIG_RAINBOW_SPEED:     return &g_config.rainbowSpeed;
        case CONFIG_RAINBOW_SMOOTH:    return &g_config.rainbowSmooth;
        case CONFIG_RAINBOW_DIRECTION: return &g_config.rainbowDirection;
        case CONFIG_GRADIENT_SPEED:    return &g_config.gradientSpeed;
        case CONFIG_GRADIENT_SMOOTH:   return &g_config.gradientSmooth;
        default: return nullptr;
    }
}

/**
 * @brief 检查并约束频段分配的总数
 * @param configItem 当前调整的配置项
 * @param newValue 新的配置值
 * @return 约束后的有效值
 */
int constrainBandAllocation(ConfigItem configItem, int newValue) {
    // 获取当前所有频段数量
    int currentBass = g_config.bassBands;
    int currentMid = g_config.midBands;
    int currentHighMid = g_config.highMidBands;
    int currentHigh = g_config.highBands;
    
    // 获取当前配置项的旧值
    int oldValue;
    switch (configItem) {
        case CONFIG_BASS_BANDS:
            oldValue = currentBass;
            currentBass = newValue;
            break;
        case CONFIG_MID_BANDS:
            oldValue = currentMid;
            currentMid = newValue;
            break;
        case CONFIG_HIGH_MID_BANDS:
            oldValue = currentHighMid;
            currentHighMid = newValue;
            break;
        case CONFIG_HIGH_BANDS:
            oldValue = currentHigh;
            currentHigh = newValue;
            break;
        default:
            return newValue; // 非频段配置，直接返回
    }
    
    // 计算总频段数
    int totalBands = currentBass + currentMid + currentHighMid + currentHigh;
    const int MAX_TOTAL_BANDS = 145; // 设置合理的总频段上限
    
    // 如果总数超限，使用更温和的约束策略
    if (totalBands > MAX_TOTAL_BANDS) {
        int excess = totalBands - MAX_TOTAL_BANDS;
        
        // 策略1：如果只是轻微超限（<=5），允许调整但限制在合理范围内
        if (excess <= 5) {
            // 计算当前配置项可以安全设置的最大值
            int otherBandsTotal = (currentBass + currentMid + currentHighMid + currentHigh) - newValue;
            int maxAllowedValue = MAX_TOTAL_BANDS - otherBandsTotal;
            
            // 获取配置范围
            const ConfigRange &range = getConfigRange(configItem);
            maxAllowedValue = constrain(maxAllowedValue, range.min, range.max);
            
            if (DEBUG_SERIAL) {
                Serial.printf("[频段约束] 轻微超限(%d)，将%s从%d调整为%d\n", 
                             excess,
                             (configItem == CONFIG_BASS_BANDS) ? "低频" :
                             (configItem == CONFIG_MID_BANDS) ? "中频" :
                             (configItem == CONFIG_HIGH_MID_BANDS) ? "中高频" : "高频",
                             newValue, maxAllowedValue);
            }
            
            return maxAllowedValue;
        }
        
        // 策略2：如果超限严重，回退到旧值并给出提示
        if (DEBUG_SERIAL) {
            Serial.printf("[频段约束] 严重超限(%d > %d)，%s保持原值%d\n", 
                         totalBands, MAX_TOTAL_BANDS,
                         (configItem == CONFIG_BASS_BANDS) ? "低频" :
                         (configItem == CONFIG_MID_BANDS) ? "中频" :
                         (configItem == CONFIG_HIGH_MID_BANDS) ? "中高频" : "高频",
                         oldValue);
            Serial.println("[频段约束] 提示：请先减少其他频段的数量");
        }
        
        return oldValue; // 返回旧值，保持不变
    }
    
    return newValue; // 总数在合理范围内，允许修改
}